package com.jdone.compus.utils;

import org.apache.commons.codec.digest.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.*;

public class SignUtil {

    private static final String CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final SecureRandom random = new SecureRandom();
    /**
     * 生成签名
     *
     * @param params 参数集合，包含待签名的参数
     * @param key    API密钥
     * @return 生成的签名sign值
     */
    public static String generateSign(Map<String, String> params, String key) {
        // 移除sign参数
        params.remove("sign");

        // 过滤空值、按参数名ASCII字典序排序
        SortedMap<String, String> sortedParams = new TreeMap<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (entry.getValue() != null && !entry.getValue().isEmpty()) {
                sortedParams.put(entry.getKey(), entry.getValue());
            }
        }

        // 构建排序后的字符串
        StringBuilder stringA = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            stringA.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        // 拼接API密钥
        stringA.append("key=").append(key);

//        System.out.println(stringA);
        // 进行MD5加密并转换为大写
        return md5(stringA.toString()).toUpperCase();
    }

    /**
     * MD5加密
     *
     * @param input 输入字符串
     * @return 加密后的字符串
     */
    private static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }

    /**
     * 生成认证签名
     */
    public static String generateSign(String appSecret, String timestamp, String randStr, String type) {
        List<String> parts = Arrays.asList(appSecret, timestamp, randStr);
        Collections.sort(parts);
        String joined = String.join("", parts);
        if ("md5".equalsIgnoreCase(type)) {
            return DigestUtils.md5Hex(joined);
        }
        return DigestUtils.sha1Hex(joined);
    }

    /**
     * 生成指定长度的随机字符串（数字+大小写字母）
     */
    public static String randomStr(int len) {
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            sb.append(CHARSET.charAt(random.nextInt(CHARSET.length())));
        }
        return sb.toString();
    }
}
